package io.gitee.cofenghen.jdbctempleplus.support;

import io.gitee.cofenghen.jdbctempleplus.annotation.Column;
import io.gitee.cofenghen.jdbctempleplus.annotation.Id;
import io.gitee.cofenghen.jdbctempleplus.annotation.Table;
import io.gitee.cofenghen.jdbctempleplus.exception.OrmException;
import io.gitee.cofenghen.jdbctempleplus.util.StringUtils;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

/**
 * 读取实体缓存
 */
public  class EntityParser {
    private static final Cache<Class<?>, EntityMeta> ENTITY_CACHE = Caffeine.newBuilder()
            .expireAfterAccess(10, TimeUnit.MINUTES)
            .maximumSize(1000)
            .build();

    public static  EntityMeta parse(Class<?> clazz) {
        return ENTITY_CACHE.get(clazz, key -> parseEntityMeta(clazz));
    }
    public static EntityMeta getCachedMeta(Class<?> clazz) {
        EntityMeta meta = ENTITY_CACHE.getIfPresent(clazz);
        if (meta == null) {
            throw new OrmException("Entity meta not found in cache: " + clazz.getName());
        }
        return meta;
    }
    private  static  EntityMeta parseEntityMeta(Class<?> clazz) {
        EntityMeta meta = new EntityMeta();
        // 解析表名
        Table table = clazz.getAnnotation(Table.class);
        meta.setTableName(table != null && !table.value().isEmpty() ? table.value() : StringUtils.camelToSnake(clazz.getSimpleName()));

        // 解析字段
        for (Field field : clazz.getDeclaredFields()) {
            Column column = field.getAnnotation(Column.class);
            String columnName=column.value() ;
            if (column != null && !column.value().isEmpty()) {//存在自定义字段@Column
                  columnName = column.value();

            }
            else
            {
                columnName =StringUtils.camelToSnake(field.getName());//小驼峰转下划线

            }

            var  fieldMeta =new  FieldMeta(field.getName(),columnName, field.getType());
            meta.addFieldMeta(field.getName(),fieldMeta );
            meta.addDataFieldMeta(columnName.toLowerCase(),fieldMeta);
            if (field.isAnnotationPresent(Id.class))//是否为主键
            {
                meta.setPrimaryKeyFieldName(columnName);
            }


        }
        return meta;
    }
}